Trò chơi Tic-Tac-Toe, game đánh caro full source code
- PhotonTransformViewPositionControl.cs
- Views /
- PhotonNetwork /
- Plugins /
- Photon Unity Networking /
- Assets /
- project /
2 using System.Collections;
3 using System.Collections.Generic;
4
5 public class PhotonTransformViewPositionControl
6 {
7 PhotonTransformViewPositionModel m_Model;
8 float m_CurrentSpeed;
9 double m_LastSerializeTime;
10 Vector3 m_SynchronizedSpeed = Vector3.zero;
11 float m_SynchronizedTurnSpeed = 0;
12
13 Vector3 m_NetworkPosition;
14 Queue<Vector3> m_OldNetworkPositions = new Queue<Vector3>();
15
16 bool m_UpdatedPositionAfterOnSerialize = true;
17
18 public PhotonTransformViewPositionControl( PhotonTransformViewPositionModel model )
19 {
20 m_Model = model;
21 }
22
23 Vector3 GetOldestStoredNetworkPosition()
24 {
25 Vector3 oldPosition = m_NetworkPosition;
26
27 if( m_OldNetworkPositions.Count > 0 )
28 {
29 oldPosition = m_OldNetworkPositions.Peek();
30 }
31
32 return oldPosition;
33 }
34
35 /// <summary>
36 /// These values are synchronized to the remote objects if the interpolation mode
37 /// or the extrapolation mode SynchronizeValues is used. Your movement script should pass on
38 /// the current speed (in units/second) and turning speed (in angles/second) so the remote
39 /// object can use them to predict the objects movement.
40 /// </summary>
41 /// <param name="speed">The current movement vector of the object in units/second.</param>
42 /// <param name="turnSpeed">The current turn speed of the object in angles/second.</param>
43 public void SetSynchronizedValues( Vector3 speed, float turnSpeed )
44 {
45 m_SynchronizedSpeed = speed;
46 m_SynchronizedTurnSpeed = turnSpeed;
47 }
48
49 /// <summary>
50 /// Calculates the new position based on the values setup in the inspector
51 /// </summary>
52 /// <param name="currentPosition">The current position.</param>
53 /// <returns>The new position.</returns>
54 public Vector3 UpdatePosition( Vector3 currentPosition )
55 {
56 Vector3 targetPosition = GetNetworkPosition() + GetExtrapolatedPositionOffset();
57
58 switch( m_Model.InterpolateOption )
59 {
60 case PhotonTransformViewPositionModel.InterpolateOptions.Disabled:
61 if( m_UpdatedPositionAfterOnSerialize == false )
62 {
63 currentPosition = targetPosition;
64 m_UpdatedPositionAfterOnSerialize = true;
65 }
66 break;
67 case PhotonTransformViewPositionModel.InterpolateOptions.FixedSpeed:
68 currentPosition = Vector3.MoveTowards( currentPosition, targetPosition, Time.deltaTime * m_Model.InterpolateMoveTowardsSpeed );
69 break;
70 case PhotonTransformViewPositionModel.InterpolateOptions.EstimatedSpeed:
71 int positionsCount = Mathf.Min( 1, m_OldNetworkPositions.Count );
72 float estimatedSpeed = Vector3.Distance( m_NetworkPosition, GetOldestStoredNetworkPosition() ) / positionsCount;
73 currentPosition = Vector3.MoveTowards( currentPosition, targetPosition, Time.deltaTime * estimatedSpeed );
74 break;
75 case PhotonTransformViewPositionModel.InterpolateOptions.SynchronizeValues:
76 if( m_SynchronizedSpeed.magnitude == 0 )
77 {
78 currentPosition = targetPosition;
79 }
80 else
81 {
82 currentPosition = Vector3.MoveTowards( currentPosition, targetPosition, Time.deltaTime * m_SynchronizedSpeed.magnitude );
83 }
84 break;
85 case PhotonTransformViewPositionModel.InterpolateOptions.Lerp:
86 currentPosition = Vector3.Lerp( currentPosition, targetPosition, Time.deltaTime * m_Model.InterpolateLerpSpeed );
87 break;
88 /*case PhotonTransformViewPositionModel.InterpolateOptions.MoveTowardsComplex:
89 float distanceToTarget = Vector3.Distance( currentPosition, targetPosition );
90 float targetSpeed = m_Model.InterpolateSpeedCurve.Evaluate( distanceToTarget ) * m_Model.InterpolateMoveTowardsSpeed;
91
92 if( targetSpeed > m_CurrentSpeed )
93 {
94 m_CurrentSpeed = Mathf.MoveTowards( m_CurrentSpeed, targetSpeed, Time.deltaTime * m_Model.InterpolateMoveTowardsAcceleration );
95 }
96 else
97 {
98 m_CurrentSpeed = Mathf.MoveTowards( m_CurrentSpeed, targetSpeed, Time.deltaTime * m_Model.InterpolateMoveTowardsDeceleration );
99 }
100
101 //Debug.Log( m_CurrentSpeed + " - " + targetSpeed + " - " + transform.localPosition + " - " + targetPosition );
102
103 currentPosition = Vector3.MoveTowards( currentPosition, targetPosition, Time.deltaTime * m_CurrentSpeed );
104 break;*/
105 }
106
107 if( m_Model.TeleportEnabled == true )
108 {
109 if( Vector3.Distance( currentPosition, GetNetworkPosition() ) > m_Model.TeleportIfDistanceGreaterThan )
110 {
111 currentPosition = GetNetworkPosition();
112 }
113 }
114
115 return currentPosition;
116 }
117
118 /// <summary>
119 /// Gets the last position that was received through the network
120 /// </summary>
121 /// <returns></returns>
122 public Vector3 GetNetworkPosition()
123 {
124 return m_NetworkPosition;
125 }
126
127 /// <summary>
128 /// Calculates an estimated position based on the last synchronized position,
129 /// the time when the last position was received and the movement speed of the object
130 /// </summary>
131 /// <returns>Estimated position of the remote object</returns>
132 public Vector3 GetExtrapolatedPositionOffset()
133 {
134 float timePassed = (float)( PhotonNetwork.time - m_LastSerializeTime );
135
136 if( m_Model.ExtrapolateIncludingRoundTripTime == true )
137 {
138 timePassed += (float)PhotonNetwork.GetPing() / 1000f;
139 }
140
141 Vector3 extrapolatePosition = Vector3.zero;
142
143 switch( m_Model.ExtrapolateOption )
144 {
145 case PhotonTransformViewPositionModel.ExtrapolateOptions.SynchronizeValues:
146 Quaternion turnRotation = Quaternion.Euler( 0, m_SynchronizedTurnSpeed * timePassed, 0 );
147 extrapolatePosition = turnRotation * ( m_SynchronizedSpeed * timePassed );
148 break;
149 case PhotonTransformViewPositionModel.ExtrapolateOptions.FixedSpeed:
150 Vector3 moveDirection = ( m_NetworkPosition - GetOldestStoredNetworkPosition() ).normalized;
151
152 extrapolatePosition = moveDirection * m_Model.ExtrapolateSpeed * timePassed;
153 break;
154 case PhotonTransformViewPositionModel.ExtrapolateOptions.EstimateSpeedAndTurn:
155 Vector3 moveDelta = ( m_NetworkPosition - GetOldestStoredNetworkPosition() ) * PhotonNetwork.sendRateOnSerialize;
156 extrapolatePosition = moveDelta * timePassed;
157 break;
158 }
159
160 return extrapolatePosition;
161 }
162
163 public void OnPhotonSerializeView( Vector3 currentPosition, PhotonStream stream, PhotonMessageInfo info )
164 {
165 if( m_Model.SynchronizeEnabled == false )
166 {
167 return;
168 }
169
170 if( stream.isWriting == true )
171 {
172 SerializeData( currentPosition, stream, info );
173 }
174 else
175 {
176 DeserializeData( stream, info );
177 }
178
179 m_LastSerializeTime = PhotonNetwork.time;
180 m_UpdatedPositionAfterOnSerialize = false;
181 }
182
183 void SerializeData( Vector3 currentPosition, PhotonStream stream, PhotonMessageInfo info )
184 {
185 stream.SendNext( currentPosition );
186
187 if( m_Model.ExtrapolateOption == PhotonTransformViewPositionModel.ExtrapolateOptions.SynchronizeValues ||
188 m_Model.InterpolateOption == PhotonTransformViewPositionModel.InterpolateOptions.SynchronizeValues )
189 {
190 stream.SendNext( m_SynchronizedSpeed );
191 stream.SendNext( m_SynchronizedTurnSpeed );
192 }
193 }
194
195 void DeserializeData( PhotonStream stream, PhotonMessageInfo info )
196 {
197 m_OldNetworkPositions.Enqueue( m_NetworkPosition );
198
199 while( m_OldNetworkPositions.Count > m_Model.ExtrapolateNumberOfStoredPositions )
200 {
201 m_OldNetworkPositions.Dequeue();
202 }
203
204 m_NetworkPosition = (Vector3)stream.ReceiveNext();
205
206 if( m_Model.ExtrapolateOption == PhotonTransformViewPositionModel.ExtrapolateOptions.SynchronizeValues ||
207 m_Model.InterpolateOption == PhotonTransformViewPositionModel.InterpolateOptions.SynchronizeValues )
208 {
209 m_SynchronizedSpeed = (Vector3)stream.ReceiveNext();
210 m_SynchronizedTurnSpeed = (float)stream.ReceiveNext();
211 }
212 }
213 }
These values are synchronized to the remote objects if the interpolation mode
or the extrapolation mode SynchronizeValues is used. Your movement script should pass on
the current speed (in unitssecond) and turning speed (in anglessecond) so the remote
object can use them to predict the objects movement.
The current movement vector of the object in unitssecond.
The current turn speed of the object in anglessecond.
Calculates the new position based on the values setup in the inspector
The current position.
Debug.Log( m_CurrentSpeed + " - " + targetSpeed + " - " + transform.localPosition + " - " + targetPosition );
Gets the last position that was received through the network
Calculates an estimated position based on the last synchronized position,
the time when the last position was received and the movement speed of the object